package JVM.第02篇_类的加载篇;

/**
 * 先从
 *                      启动类加载器 （Bootstrap）
 *                      扩展类加载器（Extension)
 *                      应用程序类加载器 （AppClassLoader）
 * Tomcat相关加载器              Common 类加载器
 *                  Catalina类加载器           Shared类在加载器
 *                                            WebApp类加载器
 *                                             Jsp类加载器
 * Tomcat 可以实现先加载
 *      WebApp类加载器在 加载 Common 类加载器
 *
 *    Tomcat先加载 WEB-INF/classes 在加载WEB-INF/lib
 *
 * 1、既然Tomcat不遵循双亲委派机制，那么如果我自己定义一个恶意的HashMap,
 *      会不会有风险呢? (阿里面试问题)
 *      答:显然不会有风险， 如果有，Tomcat都运行这么多年了，那能不改进吗?
 *      tomcat不遵循双亲委派机制，只是自定义的classLoader顺序不同，
 *      但项层还是相同的，还是要去顶层请求classloader.
 * 2、我们思考一下: Tomcat是个web容器， 那么它要解决什么问题?
 *      1.一个web容器可能需要部署两个应用程序，不同的应用程序可能会依赖同个第三方类库的不同版本，
 *      不能要求同一个类库在同一个服务器只有一份，因此要保证每个应用程序的类库都是独立的，保证相互隔离。
 *      2.部署在同一个web容器中相同的类库相同的版本可以共享。
 *      否则，如果服务器有10个应用程序，那么要有10份相同的类库加载进虚拟机，这是扯淡的。
 *      3.web容器也有自己依赖的类库，不能于应用程序的类库混淆。
 *      基于安全考虑，应该让容器的类库和程序的类库隔离开来。
 *      4.web容器要支持jsp的修改，我们知道，jsp文件最终也是要编译成class文件才能在虚拟机中运行，
 *      但程序运行后修改jsp已经是司空见惯的事情，否则要你何用?
 *      所以， web容备需要支持jsp修改后不用重启。
 * 3、Tomcat如果使用默认的类加载机制行不行?
 *      答案是不行的。为什么?我们看:
 *      第一个问题，如果使用默认的类加载器机制，那么是无法加载两个相同类库的不同版本的，
 *      默认的累加器是不管你是什么版本的，只在乎你的全限定类名，并且只有一份。
 *      第二个问题，默认的类加载器是能够实现的，因为他的职责就是保证唯一性。
 *      第三个问题和第一个问题一样。
 *      我们再看第四个问题，我们想我们要怎么实现jsp文件的热替换，jsp 文件其实也就是class文件，
 *      那么如果修改了，但类名还是一样，类加载器会直接取方法区中已经存在的，
 *      修改后的jsp是不会重新加载的。
 *      那么怎么办呢?我们可以直接卸载掉这jsp文件的类加载器，
 *      所以你应该想到了，每个jsp文件对应一个唯一的类加载器，
 *      当一个jsp文件修改了，就直接卸载这个jsp类加载器。
 *      重新创建类加载器，重新加载jsp文件。
 *
 * 4、如果tomcat的Common Classloader想加载WebApp ClassLoader中的类，该怎么办?
 *      看了前面的关于破坏双亲委派模型的内容，我们心里有数了，我们可以使用线程上下文类加载器实现，
 *      使用线程上下文加载器，可以让父类加载器请求子类加载器去完成类加载的动作。
 *
 *

 */
public class C12_Tomcat破坏双亲委派 {
    public static void main(String[] args) {
        //线程上下文的加载器
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        System.out.println(contextClassLoader);
    }

}
